package com.neusoft.aclome.cmp.cloud.server.jcce.service;

import Alg.HEFT;
import Alg.Instance;
import Alg.Schedule;
import Alg.Workflowgraph;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.neusoft.aclome.cmp.cloud.server.jcce.entity.Kt2ConsultData;
import com.neusoft.aclome.cmp.cloud.server.jcce.entity.Kt2ReportProcessEntity;
import com.neusoft.aclome.cmp.cloud.server.jcce.entity.TaskInfoToKt3;
import com.neusoft.aclome.cmp.cloud.server.jcce.feign.Kt2ReportProcessService;
import com.neusoft.aclome.cmp.cloud.server.jcce.repository.Kt2ConsultDataMapper;
import com.neusoft.aclome.cmp.cloud.server.jcce.repository.Kt2ReportProcessMapper;
import com.neusoft.aclome.cmp.cloud.server.pub.cloud.entity.CloudPlatformEntity;
import com.neusoft.aclome.cmp.cloud.server.pub.cloud.repository.CloudPlatformMapper;
import com.neusoft.aclome.cmp.cloud.server.pub.cloud.service.CloudPlatformService;
import com.neusoft.aclome.cmp.cloud.server.pub.cloud.service.PubVirtualMachineService;
import com.neusoft.aclome.cmp.cloud.server.service.DataCenterService;
import com.neusoft.aclome.cmp.cloud.server.service.VirtualMachineService;
import com.neusoft.aclome.cmp.common.model.vo.HttpResponse;
import com.neusoft.aclome.cmp.common.model.vo.ResponsePage;
import com.neusoft.pub.cloud.provider.entity.*;
import com.neusoft.pub.cloud.provider.request.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class JcceKT2Service {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private RestTemplate restTemplate = new RestTemplate();

    @Value("${jcce-url.kt3.saveTask:http://10.4.67.209:8088/kt3/saveTask}")
    private String saveTaskUrl;

    @Value("${jcce-url.kt2.prediction}")
    private String predictionUrl;

    @Value("${jcce-url.kt2.consult}")
    private String consultUrl;

    @Autowired
    private CloudPlatformMapper cloudPlatformMapper;

    @Autowired
    Kt2ReportProcessMapper kt2ReportProcessMapper;

    @Autowired
    Kt2ReportProcessService kt2ReportProcessService;

    @Autowired
    PubVirtualMachineService pubVirtualMachineService;

    @Autowired
    CloudPlatformService cloudPlatformService;

    @Autowired
    Kt2ConsultDataMapper kt2ConsultDataMapper;

    @Autowired
    private DataCenterService dataCenterService;

    @Autowired
    private VirtualMachineService privateVirtualMachineService;

    private static final Logger log = LoggerFactory.getLogger(JcceKT2Service.class);

    public void reportingProcess(JSONObject jsonObject) {
        //获取上报数据
        String reportJson = jsonObject.getJSONArray("reportJson").toJSONString();
        String cpuJson = jsonObject.getJSONArray("cpuJson").toJSONString();
        String processMap = jsonObject.getJSONObject("processMap").toJSONString();
        //获取流程数据
        String processData = jsonObject.getString("processInfo");

        Integer cpu = jsonObject.getInteger("cpu");
        Integer mem = jsonObject.getInteger("mem");
        Integer storage = jsonObject.getInteger("storage");
        //保存上报信息与流程信息
        Kt2ReportProcessEntity kt2ReportProcessEntity = new Kt2ReportProcessEntity();
        kt2ReportProcessEntity.setReportJson(reportJson);
        kt2ReportProcessEntity.setCpuJson(cpuJson);
        kt2ReportProcessEntity.setProcessMap(processMap);
        kt2ReportProcessEntity.setProcessData(processData);
        kt2ReportProcessEntity.setCreateTime(new Date());
        kt2ReportProcessEntity.setCpu(cpu);
        kt2ReportProcessEntity.setMem(mem);
        kt2ReportProcessEntity.setStorage(storage);
        kt2ReportProcessMapper.insert(kt2ReportProcessEntity);
    }

    public Kt2ReportProcessEntity processInfo(String returnId) {
        Kt2ReportProcessEntity result = new Kt2ReportProcessEntity();
        List<Kt2ReportProcessEntity> list = kt2ReportProcessMapper.selectByReturnId(returnId);
        if (!CollectionUtils.isEmpty(list)) {
            if (list.size() == 1) {
                result = list.get(0);
            } else {
                //倒序后取第一个（取时间上最新的一个）
                result = list.stream().sorted(Comparator.comparing(Kt2ReportProcessEntity::getCreateTime).reversed()).collect(Collectors.toList()).get(0);
            }
        }
        return result;
    }

    public List<JSONObject> getConfiguration(int processId,String target) {
        //调用外部接口(改为对方提供jar包，进行本地jar调用)
        //获取虚拟机信息列表
        // ListVirtualMachineRequest request = new ListVirtualMachineRequest();
        // request.setPageSize(Integer.MAX_VALUE);
        // ResponsePage<VirtualMachine> pageList = pubVirtualMachineService.listLocalInstance(request);
        // List<VirtualMachine> slList = pageList.getPageData();

        //查询流程信息
        Kt2ReportProcessEntity kt2ReportProcess = kt2ReportProcessMapper.selectByPrimaryKey(processId);
        String reportJson = "";
        String processData = "";
        String cpuData = "";
        String map = "";

        // 换成从课题2雍欣那获取的资源列表
        List<VirtualMachine> slList = new ArrayList<>();
        JSONArray arr = getConsultData("ptoc", kt2ReportProcess.getCpu() + "", kt2ReportProcess.getMem() + "", "0");
        log.info("获取资源推荐列表:" + arr.size());

        int id = 1;
        for (int i = 0; i < arr.size(); i++) {
            JSONObject j = arr.getJSONObject(i);
            JSONArray items = j.getJSONArray("items");
            for (int i2 = 0; i2 < items.size(); i2++) {
                id++;
                JSONObject item = items.getJSONObject(i2);
                VirtualMachine vm = new VirtualMachine();
                vm.setInstanceName(item.getString("instanceTypeName"));
                vm.setInstanceType(item.getString("instanceTypeName"));
                vm.setHostname(item.getString("instanceTypeName"));
                vm.setCpu(item.getInteger("cpuCoreCount"));
                vm.setMemory(item.getFloat("memorySize").intValue());
                vm.setUnitPrice(item.getString("postpaidHourPrice"));
                vm.setCloudPlatformName(j.getString("name"));
                vm.setInstanceId(id + "");
                slList.add(vm);
            }
        }
        if (kt2ReportProcess != null) {
            reportJson = kt2ReportProcess.getReportJson();
            processData = kt2ReportProcess.getProcessData();
            cpuData = kt2ReportProcess.getCpuJson();
            map = kt2ReportProcess.getProcessMap();
        }
        List<JSONObject> res = this.escalation(slList, reportJson, target, processData, cpuData, map);

        // 通知 武大 课题3 调用课题3接
        try {
            TaskInfoToKt3 kt3 = new TaskInfoToKt3();
            kt3.setCpuDemand(kt2ReportProcess.getCpu() + "");
            kt3.setMemoryDemand(kt2ReportProcess.getMem() + "");
            kt3.setStorageDemand(kt2ReportProcess.getStorage() + "");
            kt3.setStartTime(sdf.format(kt2ReportProcess.getCreateTime()));
            kt3.setArrivalTime(sdf.format(new Date()));
            List<TaskInfoToKt3.AllocationInfo> taskAllocationList = new ArrayList<>();
            for (int i = 0; i < res.size(); i++) {
                JSONObject json = res.get(i);
                TaskInfoToKt3.AllocationInfo info = new TaskInfoToKt3.AllocationInfo();
                info.setJobIndex(i + 1);
                info.setJobName(json.getString("taskName"));
                info.setCloudPlatformName(json.getString("cloudCommerce"));
                info.setInstanceType(json.getString("virtualMachineInstance"));
                // -- KT接口没反馈 反馈后增加
                // info.setCloudPlatformId();
                // info.setVirtualMachineName("VirtualMachineName");
                taskAllocationList.add(info);
            }
            kt3.setTaskAllocationList(taskAllocationList);

            log.info(JSONObject.toJSONString(kt3));
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> entity = new HttpEntity<>(JSONObject.toJSONString(kt3), headers);
            String response = getTimeOutRestTemplate().postForObject(saveTaskUrl, entity, String.class);
            log.info("课题3接口响应:"+ response);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return res;
    }

    private List<JSONObject> escalation(List<VirtualMachine> slList,String reportJson,String target,String processData,String cpuData,String map) {
        List<JSONObject> jsonList = new ArrayList<>();
        int maxTask = 3;//定义实例能够执行最大的任务
        Instance[] instances = new Instance[slList.size()];
        AlgCost.Instance[] instancesCost = new AlgCost.Instance[slList.size()];
        AlgLb.Instance[] instancesLb = new AlgLb.Instance[slList.size()];
        for (int i=0; i < slList.size(); i++){
            VirtualMachine bean = slList.get(i);
            instances[i] = new Instance(bean.getInstanceId(),bean.getHostname(),bean.getCloudPlatformName(),bean.getCpu(),
                    new BigDecimal(bean.getUnitPrice()),maxTask);
            instancesCost[i] = new AlgCost.Instance(bean.getInstanceId(),bean.getHostname(),bean.getCloudPlatformName(),bean.getCpu(),
                    new BigDecimal(bean.getUnitPrice()),maxTask);
            instancesLb[i] = new AlgLb.Instance(bean.getInstanceId(),bean.getHostname(),bean.getCloudPlatformName(),bean.getCpu(),
                    new BigDecimal(bean.getUnitPrice()),maxTask);

        }

        int[][] weight = Arrays.stream(cpuData.substring(2, cpuData.length() - 2).split("\\],\\["))
                .map(arrString -> Arrays.stream(arrString.split(","))
                        .mapToInt(s -> s.equals("null") ? 0 : Integer.parseInt(s))
                        .toArray())
                .toArray(int[][]::new);

        reportJson = reportJson.replace("null", "0");
        Gson gson = new Gson();
        int[][] array = gson.fromJson(reportJson, int[][].class);
        // 将 "null" 替换为 0
        Arrays.stream(array)
                .forEach(row -> IntStream.range(0, row.length)
                        .filter(i -> row[i] == 0)
                        .forEach(i -> row[i] = 0));

        ArrayList<int[]> resultList = new ArrayList<>(Arrays.asList(array));

        Workflowgraph workflowgraph=new Workflowgraph(weight[0].length,weight,resultList);

        AlgCost.Workflowgraph workflowgraphCost = new AlgCost.Workflowgraph(weight[0].length,weight,resultList);

        AlgLb.Workflowgraph workflowgraphLb = new AlgLb.Workflowgraph(weight[0].length,weight,resultList);

        /*****************固定值数据*********************/
        double cspinbandwidth=819; //0.8GB/s
        //csp之间带宽,前两个index是哪两个CSP,3MBps.
        double[][] cspexbandwidth=new double[][] {{0,1,102},//0.1GB
                {0,2,204},//0.2GB
                {1,2,286}};//0.28GBzhihu
        //数据传输价格 0.0002/MB 即0.2/GB
        double[] datatransmoney=new double[] {0.0001,0.0002};//分别为云内和云间
        List<Schedule> scheduledList = new ArrayList<>();
        List<AlgCost.Schedule> scheduledListCost = new ArrayList<>();
        List<AlgLb.Schedule> scheduledListLb = new ArrayList<>();
        switch (target){
            case "1":
                //填充接口参数
                HEFT heft=new HEFT(workflowgraph,cspinbandwidth, cspexbandwidth,instances,datatransmoney);
                heft.heftrun();
                //获取scheduledlist
                scheduledList=heft.getScheduledList();
                break;
            case "2":
                AlgCost.HEFT heftCost = new AlgCost.HEFT(workflowgraphCost,cspinbandwidth, cspexbandwidth,instancesCost,datatransmoney);
                scheduledListCost = heftCost.costheftrun();
                break;
            case "3":
                AlgLb.HEFT heftLb = new AlgLb.HEFT(workflowgraphLb,cspinbandwidth, cspexbandwidth,instancesLb,datatransmoney);
                heftLb.heftrun();
                scheduledListLb = heftLb.getScheduledList();
                break;
        }


        //转换数据
        Map<String, VirtualMachine> virtualMap = slList.stream()
                .collect(Collectors.toMap(VirtualMachine::getInstanceId, u -> u));
        //流程信息
        Gson gsonNew = new Gson();
        Map<String, String> processMap = gsonNew.fromJson(map, Map.class);
        //赋值
        if (!CollectionUtils.isEmpty(scheduledList)){
            for (Schedule schedule : scheduledList){
                JSONObject json = new JSONObject();
                json.put("taskName",processMap.getOrDefault(String.valueOf(schedule.getTaskindex()),""));
                VirtualMachine virtualMachine = virtualMap.get(String.valueOf(schedule.getInstanceindex()));
                if(virtualMachine != null){
                    json.put("cloudCommerce",virtualMachine.getCloudPlatformName());
                    json.put("virtualMachineType",virtualMachine.getInstanceType());
                    json.put("virtualMachineInstance",virtualMachine.getInstanceName());
                    json.put("cpuCoreCount",virtualMachine.getCpu());
                    json.put("memorySize",virtualMachine.getMemory());
                }
                jsonList.add(json);
            }
        }
        if (!CollectionUtils.isEmpty(scheduledListCost)){
            for (AlgCost.Schedule schedule : scheduledListCost){
                JSONObject json = new JSONObject();
                json.put("taskName",processMap.getOrDefault(String.valueOf(schedule.getTaskindex()),""));
                VirtualMachine virtualMachine = virtualMap.get(String.valueOf(schedule.getInstanceindex()));
                if(virtualMachine != null){
                    json.put("cloudCommerce",virtualMachine.getCloudPlatformName());
                    json.put("virtualMachineType",virtualMachine.getInstanceType());
                    json.put("virtualMachineInstance",virtualMachine.getInstanceName());
                    json.put("cpuCoreCount",virtualMachine.getCpu());
                    json.put("memorySize",virtualMachine.getMemory());
                }
                jsonList.add(json);
            }
        }
        if (!CollectionUtils.isEmpty(scheduledListLb)){
            for (AlgLb.Schedule schedule : scheduledListLb){
                JSONObject json = new JSONObject();
                json.put("taskName",processMap.getOrDefault(String.valueOf(schedule.getTaskindex()),""));
                VirtualMachine virtualMachine = virtualMap.get(String.valueOf(schedule.getInstanceindex()));
                if(virtualMachine != null){
                    json.put("cloudCommerce",virtualMachine.getCloudPlatformName());
                    json.put("virtualMachineType",virtualMachine.getInstanceType());
                    json.put("virtualMachineInstance",virtualMachine.getInstanceName());
                    json.put("cpuCoreCount",virtualMachine.getCpu());
                    json.put("memorySize",virtualMachine.getMemory());
                }
                jsonList.add(json);
            }
        }
        return jsonList;
    }

    // 杨斌
    public JSONArray getPrediction() {
        JSONArray result = new JSONArray();

        List<CloudPlatformEntity> list = cloudPlatformMapper.selectAll();
        list.forEach(cloud -> {
            JSONObject json = new JSONObject();
            JSONArray options = new JSONArray();

            json.put("cloudId", cloud.getId());
            json.put("cloudName", cloud.getPlatformName());

            // TODO: 联通暂时用阿里替代
            String cloudProvider = cloud.getCloudProvider();
            if ("WOCLOUD".equals(cloudProvider) || "VOLCENGINE".equals(cloudProvider)) {
                cloudProvider = "HUAWEI";
            }

            log.info("predictionUrl:" + predictionUrl + cloudProvider);
            String resp = restTemplate.getForObject(predictionUrl + cloudProvider, String.class, new HashMap<>());

            // 首个字段
            JSONArray nextHoureInfos = new JSONArray();
            JSONObject nextHoureInfo = new JSONObject();
            nextHoureInfo.put("memory", getFirstValue(resp,"u_mem"));
            nextHoureInfo.put("gpu", getFirstValue(resp,"u_gpu"));
            nextHoureInfo.put("cpu", getFirstValue(resp,"u_cpu"));
            nextHoureInfos.add(nextHoureInfo);
            json.put("nextHoureInfo",nextHoureInfos);

            // [{"time":2,"a_cpu":0.07158765,"u_cpu":0.14482406,"a_gpu":0.0,"u_gpu":0.04215248,"a_mem":0.14937913,"u_mem":0.18085623}]
            // 图形
            JSONObject uMemJson = getOption("预测内存", "line", resp, "u_mem", 24);
            JSONObject uCpuJson = getOption("预测CPU", "line", resp, "u_cpu", 24);
            JSONObject uGpuJson = getOption("预测GPU", "line", resp, "u_gpu", 24);
            JSONObject aMemJson = getOption("实际内存", "line", resp, "a_mem", 24);
            JSONObject aCpuJson = getOption("实际CPU", "line", resp, "a_cpu", 24);
            JSONObject aGpuJson = getOption("实际GPU", "line", resp, "a_gpu", 24);

            options.add(uMemJson);
            options.add(uCpuJson);
            options.add(uGpuJson);
            options.add(aMemJson);
            options.add(aCpuJson);
            options.add(aGpuJson);

            json.put("options", options);
            result.add(json);
        });

        return result;
    }

    private Double getFirstValue(String dataArr, String dataKey) {
        JSONArray arr = JSONArray.parseArray(dataArr);
        if (arr.size() != 0) {
            double d1 = arr.getJSONObject(0).getDouble(dataKey) * 100;
            return new BigDecimal(d1).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            log.warn("JSON 转换错误");
            return new Double(0);
        }
    }

    private JSONObject getOption(String name, String type, String dataArr, String dataKey, Integer dataSize) {
        JSONObject memOption = new JSONObject();
        memOption.put("name", name);
        memOption.put("type", type);

        List<Double> list = new ArrayList<>();
        JSONArray arr = JSONArray.parseArray(dataArr);

        for (int i = 0; i < arr.size(); i++) {
            if (i < dataSize) {
                double d1 = arr.getJSONObject(i).getDouble(dataKey)  * 100;
                double d2 = new BigDecimal(d1).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                list.add(d2);
            } else {
                break;
            }
        }

        memOption.put("data", list);
        return memOption;
    }


    // 雍欣？
    public JSONArray getConsultData(String mode, String cpu, String memory, String gpu) {
        StringBuffer url = new StringBuffer();
        url.append(consultUrl + "?");

        if (!StringUtils.isEmpty(mode)) {
            url.append("mode=" + mode + "&");
        }

        if (!StringUtils.isEmpty(cpu)) {
            url.append("cpu=" + cpu + "&");
        } else {
            url.append("cpu=4&");
        }

        if (!StringUtils.isEmpty(memory)) {
            url.append("memory=" + memory + "&");
        } else {
            url.append("memory=8&");
        }

        if (!StringUtils.isEmpty(gpu)) {
            url.append("gpu=" + gpu + "&");
        } else {
            url.append("gpu=0&");
        }

        try {
            log.info("kt2 request: " + url.toString());
            String resp = restTemplate.getForObject(url.toString(), String.class, new HashMap<>());
            log.info("kt2 response: " + resp);
            return this.dataChange(resp);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("KT接口异常，走数据库");
            List<Kt2ConsultData> list = kt2ConsultDataMapper.getOne();
            //暂时逻辑为（数据库有数据使用数据库数据，数据库没有数据调用外部接口）
            return list.get(0).getInfo();
        }

        // http://47.108.83.75/myqr?mode=price&cpu=2&memory=3&gpu=1
        // price 最低价格
        // ptoc 最优性价比
        // capacity 最高性能
    }

    private JSONArray dataChange(String resp) {
        JSONArray result = new JSONArray();
        Map<String, JSONObject> cloudMap = new HashMap<>();
        JSONArray cloudData = JSONArray.parseArray(resp);
        //拼接数据结构
        for (int i = 0; i < cloudData.size(); i++) {
            JSONObject jsonObject = cloudData.getJSONObject(i);
            String providerName = jsonObject.keySet().iterator().next();
            String arrayString = jsonObject.getString(providerName).replace("'", "\"");
            // 将 'nan' 替换为合法的 JSON 格式的 null，但保留在引号内的 'nan'
            String[] parts = arrayString.split("'");
            StringBuilder jsonStringBuilder = new StringBuilder();
            for (int y = 0; y < parts.length; y++) {
                if (y % 2 == 0) {
                    jsonStringBuilder.append(parts[y].replace("nan", "null"));
                } else {
                    jsonStringBuilder.append("'").append(parts[y]).append("'");
                }
            }
            String jsonString = jsonStringBuilder.toString();
            // 将字符串转换为 JSONArray 对象
            JSONArray dataArray = JSON.parseArray(jsonString);
            // 创建最终结果的JSONObject
            JSONObject resultObject = new JSONObject();

            //详细信息
            JSONObject itemObject = new JSONObject();
            itemObject.put("instanceTypeFamily", dataArray.getString(5));
            itemObject.put("instanceTypeName", dataArray.getString(6));
            itemObject.put("cpuCoreCount", dataArray.get(1));
            itemObject.put("memorySize", dataArray.get(7));
            itemObject.put("arch", dataArray.getString(0));
            itemObject.put("processorModel", dataArray.getString(9));
            itemObject.put("gpuSpec", dataArray.getString(3));
            itemObject.put("gpuMemorySize", dataArray.getString(2));
            itemObject.put("gpuAmount", dataArray.getString(2));
            itemObject.put("postpaidHourPrice", dataArray.getDoubleValue(8));

            JSONArray items = new JSONArray();
            items.add(itemObject);
            //判断是否存在
            JSONObject cloudInfo = cloudMap.getOrDefault(providerName,null);
            if (cloudInfo != null){
                BigDecimal oldTotalPrice = new BigDecimal(cloudInfo.getDouble("totalPrice"));
                BigDecimal newTotalPrice = new BigDecimal(dataArray.getDoubleValue(8));
                BigDecimal totalPrice = oldTotalPrice.add(newTotalPrice);
                totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
                cloudInfo.put("totalPrice",totalPrice);
                cloudInfo.getJSONArray("items").add(itemObject);
            }else {
                // 设置"name"字段
                resultObject.put("name", providerName);
                resultObject.put("totalPrice", dataArray.getDoubleValue(8));
                resultObject.put("items",items);
                cloudMap.put(providerName,resultObject);
            }
        }
        cloudMap.forEach((key, value) ->
                result.add(value)
        );
        return result;
    }


    //  课题2概览页面
    public HttpResponse kt2Overview() {
        JSONArray resArr = new JSONArray();

        // 公私有云云商列表
        List<CloudPlatformEntity> publicList = cloudPlatformService.getCloudPlatformList(new CloudPlatformRequest()).getPageData();

        // 公私有云虚拟机
        ListVirtualMachineRequest pubReq = new ListVirtualMachineRequest();
        pubReq.setPageNumber(1);
        pubReq.setPageSize(1000);
        List<VirtualMachine> pubVMs = pubVirtualMachineService.listLocalInstance(pubReq).getPageData();

        for (int i = 0; i < publicList.size(); i++) {
            CloudPlatformEntity cloud = publicList.get(i);
            JSONObject resJson = new JSONObject();
            resJson.put("id", cloud.getId());
            resJson.put("platformName", cloud.getPlatformName());
            resJson.put("cloudProvider", cloud.getCloudProvider());

            long cpuTotal = cloud.getCpuQuota();
            long memTotal = cloud.getMemQuota();
            long storageTotal = cloud.getCapacityQuota();
            long bandwidthTotal = cloud.getBandwidthQuota();

            List<VirtualMachine> vmList = pubVMs.stream().filter(vm -> vm.getDataCenterId().equals(cloud.getId())).collect(Collectors.toList());

            // 通过虚拟机查已用配额
            long cpuValue = vmList.stream().mapToLong(vm -> vm.getCpu() == null ? 0 : vm.getCpu()).sum();
            long memValue = vmList.stream().mapToLong(vm -> vm.getMemory() == null ? 0 : vm.getMemory()).sum() / 1024;
            long bandwidthValue = vmList.stream().mapToLong(vm -> vm.getInternetMaxBandwidthOut() != null ? vm.getInternetMaxBandwidthOut() : 0).sum();

            // TODO 目前虚拟机表没保存存储 暂时替代
            Integer storageValue = new Double(((double) cpuValue / (double) cpuTotal) * storageTotal).intValue();

            resJson.put("cpuTotal", cpuTotal);
            resJson.put("memTotal", memTotal);
            resJson.put("storageTotal", storageTotal);
            resJson.put("bandwidthTotal", bandwidthTotal);

            resJson.put("cpuValue", cpuValue);
            resJson.put("memValue", memValue);
            resJson.put("storageValue", storageValue);
            resJson.put("bandwidthValue", bandwidthValue);

            resArr.add(resJson);
        }

        return HttpResponse.resultSuccess(resArr);
    }


    public RestTemplate getTimeOutRestTemplate() {
        int timeout = 6000; // 5 seconds
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(timeout);
        requestFactory.setReadTimeout(timeout);
        return new RestTemplate(requestFactory);
    }

}
